{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "70247a4734560d05",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# State Resetting\n",
    "\n",
    "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brainpy/brainpy/blob/master/docs_version2/tutorial_toolbox/state_resetting.ipynb)\n",
    "[![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/brainpy/brainpy/blob/master/docs_version2/tutorial_toolbox/state_resetting.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9779820747370f40",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "State resetting is useful when simulating and training recurrent neural networks. \n",
    "\n",
    "Similar to [state saving and loading](./saving_and_loading.ipynb) , state resetting is implemented with two functions:\n",
    "\n",
    "- a local function ``.reset_state()`` which resets all local variables in the current node.\n",
    "- a global function ``brainpy.reset_state()`` which resets all variables in parent and children nodes."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62235021ef5d0fc5",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "Let's define a simple example:"
   ]
  },
  {
   "cell_type": "code",
   "id": "c52235597a78e7a9",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-10-06T05:17:01.759811Z",
     "start_time": "2025-10-06T05:16:57.361854Z"
    }
   },
   "source": [
    "import brainpy as bp\n",
    "import brainpy.math as bm\n",
    "\n",
    "class EINet(bp.DynSysGroup):\n",
    "    def __init__(self):\n",
    "      super().__init__()\n",
    "      self.N = bp.dyn.LifRefLTC(4000, V_rest=-60., V_th=-50., V_reset=-60., tau=20., tau_ref=5.,\n",
    "                                V_initializer=bp.init.Normal(-55., 2.))\n",
    "      self.delay = bp.VarDelay(self.N.spike, entries={'I': None})\n",
    "      self.E = bp.dyn.ProjAlignPost1(comm=bp.dnn.EventJitFPHomoLinear(3200, 4000, prob=0.02, weight=0.6),\n",
    "                                     syn=bp.dyn.Expon(size=4000, tau=5.),\n",
    "                                     out=bp.dyn.COBA(E=0.),\n",
    "                                     post=self.N)\n",
    "      self.I = bp.dyn.ProjAlignPost1(comm=bp.dnn.EventJitFPHomoLinear(800, 4000, prob=0.02, weight=6.7),\n",
    "                                     syn=bp.dyn.Expon(size=4000, tau=10.),\n",
    "                                     out=bp.dyn.COBA(E=-80.),\n",
    "                                     post=self.N)\n",
    "\n",
    "    def update(self, input):\n",
    "      spk = self.delay.at('I')\n",
    "      self.E(spk[:3200])\n",
    "      self.I(spk[3200:])\n",
    "      self.delay(self.N(input))\n",
    "      return self.N.spike.value"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "cell_type": "code",
   "id": "d86ace387ad37c42",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-10-06T05:17:02.313937Z",
     "start_time": "2025-10-06T05:17:01.763821Z"
    }
   },
   "source": [
    "net = EINet()"
   ],
   "outputs": [],
   "execution_count": 2
  },
  {
   "cell_type": "markdown",
   "id": "fa6bf0dac07d7ee5",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "By calling ``brainpy.reset_state(net)``, we can reset all states in this network, including variables in the neurons, synapses, and networks. By using ``net.reset_state()``, we can reset the local variables which are defined in the current network. "
   ]
  },
  {
   "cell_type": "code",
   "id": "dc4233aa2c611eb2",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-10-06T05:17:02.326073Z",
     "start_time": "2025-10-06T05:17:02.318924Z"
    }
   },
   "source": [
    "print('Before reset:', net.N.V.value)\n",
    "bp.reset_state(net)\n",
    "print('After reset:', net.N.V.value)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Before reset: [-58.220734 -55.27516  -52.99294  ... -53.753098 -58.306976 -54.8126  ]\n",
      "After reset: [-52.719162 -59.424145 -55.10583  ... -55.06449  -55.02565  -55.455853]\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "id": "eb07adbfa355e58e",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-10-06T05:17:02.336121Z",
     "start_time": "2025-10-06T05:17:02.330307Z"
    }
   },
   "source": [
    "print('Before reset_state:', net.N.V.value)\n",
    "net.reset_state()\n",
    "print('After reset_state:', net.N.V.value)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Before reset_state: [-52.719162 -59.424145 -55.10583  ... -55.06449  -55.02565  -55.455853]\n",
      "After reset_state: [-58.49746  -53.042305 -52.38119  ... -57.445927 -52.89065  -56.70536 ]\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "markdown",
   "id": "c798a702ce23dedc",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "There is no change for the ``V`` variable, meaning that the network's ``reset_state()`` can not reset states in the children node. Instead, to reset the whole states of the network, users should use ``brainpy.reset_state()`` function. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
